#include "thread_try.h"

// ! CMake后直接编译会报错，因为pthread不是ANSI C的标准库
// ! pthread 只是Linux的一个第三方库

typedef struct thread_function_args
{
    char * thd_name;
    int  thd_num;
} thd_args;

void * a_thread(void * arg){
    // pthread_create 以void* 形式传递地址指针，因此类型转换需要自己做
    thd_args * args = (thd_args *) arg;
    printf("在线程 %s中", args->thd_name);
    for (int i=0; i<3; i++)
        printf("线程[%s]在运行：%d次 -- %d\n",  args->thd_name, i, args->thd_num);
    return 0;
}


int main(void){
    pthread_t thread_id;

    int arg1 = 1;
    int arg2 = 2;

    //  pthread_create接受四个参数
    // * 第一个参数是线程号，创建成功后会给里面写入创建的现成的tid
    // 主程序如果想要操作线程就需要线程的tid，因此要传地址
    // * 第二个参数是创建线程时的属性，
    // 例如开辟的栈的大小等等，诸多信息保存在pthread_attr_t这个结构体里面
    // 如果指定为NULL的话会使用默认的设置
    // * 第三个参数是一个指向void *的函数的函数指针
    // 注意要传入的是该函数的地址，因此函数名即可
    // 创建线程后线程的线程映像就是函数指针指向的函数，即后续线程将执行这个线程
    // * 第四个参数是为函数指针传入的参数
    // 注意要求是一个指向void * 的指针，因此取地址之后要转换A
    // * pthred 返回值的整数， ret为1表示创建成功，0表示创建失败
    // == 创建失败之后用perror来获取错误信息，错误信息会被放到errno这个系统变量中
    // == perror会去读取这个信息，因此需要include errno.h
    thd_args args;
    args.thd_name = "thread 1";
    args.thd_num = 1;

    printf("创建线程...\n");
    // 若创建成功，返回0；若出错，则返回错误编号
    int ret = pthread_create(&thread_id, NULL, a_thread, (void *) &args);
    
    if (ret){
        perror("pthread_create\n");
        printf("pthread_create\n");
        exit(-1);
    }

    // 手动调用
    // a_thread((void *) &arg2);

    // * pthread_join 用于挂起主进程，等待子进程结束，并获得其返回值
    // * 返回值将被写入status中
    void * status;
    pthread_join(thread_id,  &status);
    printf("线程返回%d", (int)status);

    return 0;
}